// Copyright (C) 2021-2021 wuchengwen. All Rights Reserved.
// Description: 线程池相关头文件
// Author : wuchengwen <wuchw@foxmail.com>
// Date :2021-07-09

#pragma once

#include <mutex>
#include <queue>
#include <vector>
#include <condition_variable>
#include <thread>
#include <functional>

// 线程池定义
class ThreadPool {
public:
    ThreadPool(uint32_t minNum, uint32_t maxNum);
    ~ThreadPool();

    // 添加任务
    bool AddTask(std::function<void(void)> &&func) noexcept;

private:
    static void worker(ThreadPool &pool) noexcept;
    static void manager(ThreadPool &pool) noexcept;
    std::vector<std::thread> threads_; // 所有线程
    uint32_t minNum_;                  // 最小线程数量
    uint32_t maxNum_;                  // 最大线程数量
    uint32_t busyNum_ = 0;             // 忙的线程数量
    uint32_t exitNum_ = 0;             // 需要退出的线程数量
    uint32_t liveNum_ = 0;             // 存活的线程数量
    std::thread manageThread_;         // 管理者线程
    std::mutex poolMutex_;             // 防止多线程修改时出现同步问题
    std::mutex busyMutex_;             // 因为要反复执行任务，修改忙线程数量，所以busyNum_单独使用锁保护
    std::condition_variable notEmpty_; // 如果队列不空，才能执行任务。添加任务了，队列才不会空
    std::condition_variable notFull_;  // 如果队列不满，才能添加任务，如果任务被执行了，则队列不满

    std::queue<std::function<void(void)>> taskQue_; // 任务队列
    uint32_t queCap_ = 80;                          // 任务队列容量
    bool shutDown_;
};